package org.sgx.gapigui.client.control;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.sgx.gapi.client.apis.books.Volume;
import org.sgx.gapi.client.apis.books.VolumeList;
import org.sgx.gapi.client.apis.books.VolumeListRequest;
import org.sgx.gapi.client.apis.fusiontables.FTTable;
import org.sgx.gapi.client.apis.fusiontables.table.TableListRequest;
import org.sgx.gapi.client.apis.fusiontables.table.TableListResult;
import org.sgx.gapi.client.apis.urlshortener.UrlResource;
import org.sgx.gapi.client.apis.urlshortener.UrlShortenerGetRequest;
import org.sgx.gapi.client.apis.urlshortener.UrlShortenerInsertRequest;
import org.sgx.gapi.client.apis.youtube.Search;
import org.sgx.gapi.client.apis.youtube.SearchRequest;
import org.sgx.gapi.client.apis.youtube.SearchResponse;
import org.sgx.gapi.client.client.GAPICallback;
import org.sgx.gapi.client.client.GAPIResult;
import org.sgx.gapigui.client.ui.editableModels.books.Book;
import org.sgx.gapigui.client.ui.editableModels.ft.Table;
import org.sgx.gapigui.client.ui.editableModels.ft.TableCreateCommand;
import org.sgx.gapigui.client.ui.editableModels.urlShortener.Url;
import org.sgx.gapigui.client.ui.editableModels.youtube.Video;

import com.google.gwt.user.client.Window;

public class MainController1 implements MainController {
	private static MainController instance;

	private List<WorkListener> workListeners;

	private MainController1() {
		workListeners = new LinkedList<WorkListener>();
	}

	public static MainController getInstance() {
		if (instance == null)
			instance = new MainController1();
		return instance;
	}
	
	
	
	
	//working flag

	private boolean working;
	String workingMsg;

	/* (non-Javadoc)
	 * @see org.sgx.gapigui.client.control.MainController#addWorkListener(org.sgx.gapigui.client.control.WorkListener)
	 */
	@Override
	public void addWorkListener(WorkListener l) {
		workListeners.add(l);
	}

	public boolean isWorking() {
		return working;
	}

	public void setWorking(boolean w) {
		if (working != w) {
			this.working = w;
			notifyAllWorkListeners();
		}
	}

	public void notifyAllWorkListeners() {
		for (WorkListener l : workListeners) {
			l.notifyWorkChange(isWorking());
		}
	}
	
	
	
	//system calls
	

//	/* (non-Javadoc)
//	 * @see org.sgx.gapigui.client.control.MainController#showTablesView()
//	 */
//	@Override
//	public void showTablesView() {
//		// TODO Auto-generated method stub
//		
//	}
	
	protected void dispatchGapiError(GAPIResult result) {
		System.out.println("*** GAPI ERROR: "+result.error().message());
	}

	@Override
	public void doTableCreate(TableCreateCommand tcc) {

		FTTable table = FTTable.create().name(tcc.getName()).description("tcc.getDescription()")
				.isExportable(tcc.getIsExportable());
		
		//TODO
	}

	/* (non-Javadoc)
	 * @see org.sgx.gapigui.client.control.MainController#doListTables()
	 */
	@Override
	public void doTableList(final ControllerCallback<List<Table>> callback) {
		new TableListRequest().execute(
		new GAPICallback<TableListResult>() {			
			@Override
			public void call(TableListResult result) {				

				if (result.error() != null) {
					dispatchGapiError(result); 
//					log("error : " + result.error().message());
				} else {
					List<Table> l = new LinkedList<Table>();
					for(FTTable table : result.itemsCol()) 
						l.add(Table.from(table)); 					
					callback.call(l); 
				}
			}
		});
	}
	
	
	@Override
	public void doBookSearch(String keywords, final ControllerCallback<List<Book>> callback) {
		new VolumeListRequest(keywords).execute(new GAPICallback<VolumeList>() {			
			@Override
			public void call(VolumeList result) {
				if (result.error() != null) {
					dispatchGapiError(result);//log("error : " + result.error().message());
				} else {
					List<Book> l = new LinkedList<Book>();
					for(Volume v : result.itemsCol()) 
						l.add(Book.from(v)); 					
					callback.call(l); 
				}
			}
		}); 
	}
	
	@Override
	public void doYoutubeSearch(String text, final ControllerCallback<List<Video>> callback) {
		SearchRequest req = new SearchRequest();
		req.setPart("id,snippet"); 
		req.setQ(text); 
		req.setType("video"); 
		req.execute(new GAPICallback<SearchResponse>() {
			@Override
			public void call(SearchResponse result) {
				if(result.error()!=null) {
					dispatchGapiError(result);
//					Window.alert("Error on Youtube Search request: "+result.error().message()); 
				}
				else {
					Collection<Search> items = result.itemsCol();
					List<Video> l = new LinkedList<Video>(); 
					String titles = ""; 
					for(Search s : items) {
						Video v = Video.from(s); 
						l.add(v); 
						titles+=s.snippet().title()+", ";
					}
//					Window.alert("Youtube Search response first "+items.size()+" titles : "+titles);
					callback.call(l); 
				}
			}
		}); 
	}
	
	

	@Override
	public void urlShortenerGetOriginal(String value, final ControllerCallback<Url> callback) {
		new UrlShortenerGetRequest(value).execute(new GAPICallback<UrlResource>() {
			@Override
			public void call(UrlResource result) {
				if (result.error() != null)
					dispatchGapiError(result);//Gallery.getInstance().log("ERROR: " + JsUtil.dumpObj(result.error(), true));
				else
					//Gallery.getInstance().log("Long url : " + result.longUrl());
					callback.call(Url.from(result));
			}
		});
	}

	@Override
	public void urlShortenerInsert(String longUrl, final ControllerCallback<Url> callback) {
		UrlShortenerInsertRequest insertReq = new UrlShortenerInsertRequest(longUrl);
		insertReq.execute(new GAPICallback<UrlResource>() {
			@Override
			public void call(UrlResource result) {
				if (result.error() != null)
					dispatchGapiError(result);//Gallery.getInstance().log("INSERT ERROR: " + result.error().message());
				else
					callback.call(Url.from(result));
//					Gallery.getInstance().log("INSERT new short url: " + result.id());
			}
		});
	}

	


}
